package com.kedacom.demo.ad.model;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.ldap.core.AttributesMapper;

public class ADUser {

	private String cn;
	private String displayName; // 显示名称
	private String sn; // 姓
	private String givenName; // 名
	private String initials; // 英文缩写
	private String description; // 描述
	private String physicalDeliveryOfficeName; // 办公室
	private String telephoneNumber; // 电话号码
	private String otherTelephone; // 其它电话号码，多个以英文分号分隔
	private String mail; // 电子邮件
	private String streetAddress; // 街道
	private String userPrincipalName; // 用户登录名
	private String sAMAccountName; // 用户登录名（以前版本）
	private String userAccountControl; // 用户帐户控制 (启用：512，禁用：514 -- 512 + 2，
										// 密码永不过期：66048 -- 65536 + 512，
										// 用户禁用：66050 -- 65536 + 512 + 2)
	private String title; // 职务
	private String department; // 部门
	private String company; // 公司
	private String memberOf; // 隶属于，用户组的DN不需使用引号，多个用分号分隔
	private String manager; // Manager
	private String mobile; // Mobile
	private String info; // Notes

	private static String[] fieldNames;

	static {
		Field[] fields = ADUser.class.getDeclaredFields();
		List<String> fieldNamesList = new ArrayList<String>();
		for (Field field : fields) {
			fieldNamesList.add(field.getName());
		}
		fieldNames = new String[fieldNamesList.size()];
		fieldNames = fieldNamesList.toArray(fieldNames);
	}

	public static class ADUserAttributesMapper implements AttributesMapper<ADUser> {

		public static Map<String, String> attributeNames = new HashMap<String, String>();

		public ADUser mapFromAttributes(Attributes attributes) throws NamingException {
			try {
				printAttributes(attributes);
				collectAttributeNames(attributes);
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}

			ADUser user = new ADUser();
			for (String attr : fieldNames) {
				try {
					BeanUtils.setProperty(user, attr, get(attributes, attr));
				} catch (IllegalAccessException | InvocationTargetException e) {
					e.printStackTrace();
				}
			}
			return user;
		}

		private void collectAttributeNames(Attributes attributes) {
			NamingEnumeration<?> attributesEnum = attributes.getAll();
			while (attributesEnum.hasMoreElements()) {
				try {
					Attribute attribute = (Attribute) attributesEnum.next();
					String attrKey = attribute.getID();
					Object attrValue = attribute.get();
					attributeNames.put(attrKey, attrValue.getClass().toString());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		private void printAttributes(Attributes attributes) throws UnsupportedEncodingException {
			NamingEnumeration<?> attributesEnum = attributes.getAll();
			Map<String, Object> map = new HashMap<String, Object>();
			while (attributesEnum.hasMoreElements()) {
				try {
					Attribute attribute = (Attribute) attributesEnum.next();
					String attrKey = attribute.getID();
					Object attrValue = attribute.get();

					if ("objectSid".equalsIgnoreCase(attrKey) || "objectSid".equalsIgnoreCase(attrKey)) {
						map.put(attrKey, getGUID(attrValue.toString().getBytes()));
					} else if ("logonHours".equalsIgnoreCase(attrKey)) {
						// System.out.println(attrValue.getClass());
						// String str = (String) attrValue;
						// System.out.println(str.equals(new
						// String(str.getBytes("UTF-8"), "UTF-8")));
						// System.out.println(str.equals(new
						// String(str.getBytes("GBK"), "GBK")));
						// System.out.println(str.equals(new
						// String(str.getBytes("GB2312"), "GB2312")));
						// System.out.println(str.equals(new
						// String(str.getBytes("ISO-8859-1"), "ISO-8859-1")));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "UTF-8"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "GBK"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "GB2312"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "ISO-8859-1"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "ASCII"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "Unicode"));
						// System.out.println(new String(str.getBytes("UTF-8"),
						// "GB18030"));
						// System.out.println(getGUID(attrValue.toString().getBytes()));
						// System.out.println(getGUID(str.getBytes()));
					} else {
						map.put(attrKey, attrValue);
					}
				} catch (NamingException e) {
					e.printStackTrace();
				}
			}
			// System.out.println(JacksonUtils.toJsonString(map));
		}

		private String getGUID(byte[] inArr) {
			StringBuffer guid = new StringBuffer();
			for (int i = 0; i < inArr.length; i++) {
				StringBuffer dblByte = new StringBuffer(Integer.toHexString(inArr[i] & 0xff));
				if (dblByte.length() == 1) {
					guid.append("0");
				}
				guid.append(dblByte);
			}
			return guid.toString();
		}

		private String get(Attributes attributes, String attrID) throws NamingException {
			Attribute attribute = attributes.get(attrID);
			return attribute == null ? null : (String) attribute.get();
		}

	}

	public String getCn() {
		return cn;
	}

	public void setCn(String cn) {
		this.cn = cn;
	}

	public String getDisplayName() {
		return displayName;
	}

	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public String getSn() {
		return sn;
	}

	public void setSn(String sn) {
		this.sn = sn;
	}

	public String getGivenName() {
		return givenName;
	}

	public void setGivenName(String givenName) {
		this.givenName = givenName;
	}

	public String getInitials() {
		return initials;
	}

	public void setInitials(String initials) {
		this.initials = initials;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getTelephoneNumber() {
		return telephoneNumber;
	}

	public void setTelephoneNumber(String telephoneNumber) {
		this.telephoneNumber = telephoneNumber;
	}

	public String getMail() {
		return mail;
	}

	public void setMail(String mail) {
		this.mail = mail;
	}

	public String getStreetAddress() {
		return streetAddress;
	}

	public void setStreetAddress(String streetAddress) {
		this.streetAddress = streetAddress;
	}

	public String getUserPrincipalName() {
		return userPrincipalName;
	}

	public void setUserPrincipalName(String userPrincipalName) {
		this.userPrincipalName = userPrincipalName;
	}

	public String getUserAccountControl() {
		return userAccountControl;
	}

	public void setUserAccountControl(String userAccountControl) {
		this.userAccountControl = userAccountControl;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public String getCompany() {
		return company;
	}

	public void setCompany(String company) {
		this.company = company;
	}

	public String getManager() {
		return manager;
	}

	public void setManager(String manager) {
		this.manager = manager;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getInfo() {
		return info;
	}

	public void setInfo(String info) {
		this.info = info;
	}

	public String getPhysicalDeliveryOfficeName() {
		return physicalDeliveryOfficeName;
	}

	public void setPhysicalDeliveryOfficeName(String physicalDeliveryOfficeName) {
		this.physicalDeliveryOfficeName = physicalDeliveryOfficeName;
	}

	public String getOtherTelephone() {
		return otherTelephone;
	}

	public void setOtherTelephone(String otherTelephone) {
		this.otherTelephone = otherTelephone;
	}

	public String getsAMAccountName() {
		return sAMAccountName;
	}

	public void setsAMAccountName(String sAMAccountName) {
		this.sAMAccountName = sAMAccountName;
	}

	public String getMemberOf() {
		return memberOf;
	}

	public void setMemberOf(String memberOf) {
		this.memberOf = memberOf;
	}

}
